﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using DeepForest.Phone.Assets.Tools;
using Lasalara.Model;
using Lasalara.ViewModel;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Net.NetworkInformation;
using Microsoft.Phone.Shell;
using RestSharp;
using GestureEventArgs = System.Windows.Input.GestureEventArgs;
using System.Collections.ObjectModel;
using Microsoft.Phone.Reactive;

namespace Lasalara.View
{               
    public partial class Study
    {
        private readonly StudyViewModel _studyViewModel = new StudyViewModel();
        private ApplicationBarMenuItem _proposeQuestionItem;
        private ApplicationBarIconButton _pageViewButton;
        private ApplicationBarIconButton _textSizeButton;
        private ApplicationBarIconButton _switchButton;
        private ApplicationBarIconButton _randomizeButton;
        private int _tapCount;
        private ListBoxItem _selectedQuestion;
        private double _questionsLoaded;
        private bool _changingFont;
        private bool _questionsScrambled;

        public Study()
        {
            InitializeComponent();
            Loaded += StudyLoaded;
        }

        private void StudyLoaded(object sender, RoutedEventArgs e)
        {
            ShowHide(LayoutRoot, null, RenderSize.Width, 0, 0, 1);
        }

        protected override void OnNavigatedTo(NavigationEventArgs navigationEventArgs)
        {
            GlobalViewModel.SetLogo(logoStudyView, logoStudyViewRectangle, "logo3");
            //Set default font size
            if (App.CurrentUser.CurrentFontSize == 0)
            {
                App.CurrentUser.CurrentFontSize = 20;
            }
            // Set user font if it has been set before.
            if (App.CurrentUser.CurrentFontSize > 0)
            {
                ApplyFontSize(App.CurrentUser.CurrentFontSize);
            }

            InitializeStudyMode();

            studyPivot.Items.Remove(sendQuestionPivotItem); // remove propose question pivot item
            studyPivot.Items.Remove(pageViewPivotItem);

            CreateAppBar();

            sendQuestionButton.Click += SendQuestionButtonClick;
            UpdateChapterProgress();

            if (NavigationContext.QueryString.ContainsKey("fromSponsor"))
            {
                if (NavigationContext.QueryString.ContainsKey("toPageView"))
                {
                    PageViewButtonClick(new object(), new EventArgs());
                }
            }
            NavigationService.RemoveBackEntry();
            NavigationContext.QueryString.Clear();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // Update the books progress when navigating away from study page.
            BookViewModel.UpdateBookProgress(App.CurrentUser.CurrentBook);
            App.CurrentUser.InsertChapterToDownloadedBook();
            GlobalViewModel.UpdateLiveTileProgress(App.CurrentUser);
            GlobalViewModel.HideProgressBar(trayProgressBar);
        }

        /// <summary>
        /// Sets the first question visible, creates animations for answer
        /// </summary>
        private void InitializeStudyMode()
        {
            if (App.CurrentUser.CurrentChapter.CurrentQuestion == null)
            {
                App.CurrentUser.CurrentChapter.CurrentQuestion = App.CurrentUser.CurrentChapter.Questions.First(x => x.AnsweredDate < DateTime.Now);
            }
            questionText.Text = App.CurrentUser.CurrentChapter.CurrentQuestion.QuestionText;
            answerText.Text = App.CurrentUser.CurrentChapter.CurrentQuestion.AnswerText;
        }

        /// <summary>
        /// Hides or shows the check mark in the i know the anwer button image.
        /// </summary>
        private void KnowAnswerPressed(bool isChecked)
        {
            if (isChecked)
            {
                knowAnswerButton.Fill = (Brush)Application.Current.Resources["PhoneForegroundBrush"];
            }
            else
            {
                fadeInTransition.Begin();
                knowAnswerButton.Fill = (Brush)Application.Current.Resources["PhoneAccentBrush"];
            }
        }

        /// <summary>
        /// Displays first available question. Is used if the currentquestion is not set yet.
        /// </summary>
        private void DisplayFirstQuestion()
        {
            App.CurrentUser.CurrentChapter.CurrentQuestion = App.CurrentUser.CurrentChapter.Questions.FirstOrDefault(x => x.AnsweredDate < DateTime.Now);
            if (App.CurrentUser.CurrentChapter.CurrentQuestion != null)
            {
                questionText.Text = App.CurrentUser.CurrentChapter.CurrentQuestion.QuestionText;
                answerText.Text = App.CurrentUser.CurrentChapter.CurrentQuestion.AnswerText;
                answerBorder.Visibility = Visibility.Collapsed;
                answerText.Visibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// Update chapter progressbar.
        /// </summary>
        private void UpdateChapterProgress()
        {
            App.CurrentUser.CurrentChapter.Progress = Chapter.GetChapterProgress(App.CurrentUser.CurrentChapter);
            chapterProgressBar.Value = App.CurrentUser.CurrentChapter.Progress;
        }

        /// <summary>
        /// Updates the font for text displayed in page view
        /// </summary>
        private void UpdatePageViewFontSize(double fontSize)
        {
            var questions = App.CurrentUser.CurrentChapter.Questions.ToList();
            foreach (Question q in questions)
            {
                q.FontSize = fontSize;
            }
            App.CurrentUser.CurrentChapter.Questions = questions;
        }

        private void ShowAppBar(bool show)
        {
            ApplicationBar.IsVisible = show;
        }

        /// <summary>
        /// Scrolls to the right question in page view
        /// </summary>
        private void ScrollToQuestion()
        {
            questionsListBox.UpdateLayout();
            if (questionsListBox.SelectedItem != null)
            {
               /* 
                if (questionsListBox.SelectedIndex == questionsListBox.Items.Count-1)
                    questionsListBox.ScrollIntoView(questionsListBox.Items.First());
                else
                    questionsListBox.ScrollIntoView(questionsListBox.Items.Last());
                */
                questionsListBox.ScrollIntoView(questionsListBox.SelectedItem);
                questionsListBox.UpdateLayout();
            }
            questionsListBox.SelectedIndex = -1;
        }

        /// <summary>
        /// Updates the list of questions displayed in page view
        /// </summary>
        private void UpdatePageViewList()
        {
            QuestionsLoading();
            var questions = App.CurrentUser.CurrentChapter.Questions.ToList();
            questionsListBox.ItemsSource = new ObservableCollection<Question>();
            questions.ToObservable().
            Zip(Observable.Interval(TimeSpan.FromMilliseconds(25)), (d, t) => d).
            ObserveOnDispatcher().
            Subscribe(AddQuestion, QuestionsNotLoading);
        }

        /// <summary>
        /// Adds a question to the list that's displayed in page view.
        /// </summary>
        /// <param name="question">Question to be added</param>
        private void AddQuestion(Question question)
        {
            trayProgressBar.Value = _questionsLoaded/App.CurrentUser.CurrentChapter.Questions.Count;

            var source = questionsListBox.ItemsSource as ObservableCollection<Question>;
            if (source == null) return;
            // Add to list only if the chapter is not already there.
            question.FontSize = App.CurrentUser.CurrentFontSize;
            source.Add(question);
            _questionsLoaded++;
            // Scroll back to first when it is added question
            if (_questionsLoaded == 1)
            {
                questionsListBox.UpdateLayout();
                questionsListBox.ScrollIntoView(questionsListBox.Items.First());
            }
            // If the current question is loaded, scroll to it
            if (question.Equals(App.CurrentUser.CurrentChapter.CurrentQuestion) && !_questionsScrambled)
            {
                questionsListBox.ScrollIntoView(questionsListBox.Items.Last());           
            }
        }

        /// <summary>
        /// Toggles the answer control's visibility on page view screen
        /// </summary>
        ///  <param name="targetElement">List element the control belongs to</param>
        /// <param name="controlName">Name of the control</param>
        private void ToggleAnswerVisibility(DependencyObject targetElement, string controlName)
        {
            var count = VisualTreeHelper.GetChildrenCount(targetElement);
            if (count == 0)
                return;

            for (var i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(targetElement, i);
                var targetItem = (FrameworkElement)child;
                if (targetItem.Name == controlName)
                {
                    if (controlName == "answerPageViewBorder")
                    {
                        targetItem.Visibility = targetItem.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
                    }
                    else if (targetItem.Visibility == Visibility.Visible)
                    {
                        fadeOutPageAnswerTransition.Stop();
                        Storyboard.SetTarget(fadeOutTextAnimation, targetItem);
                        EventHandler handler = null;
                        handler = (s, args) =>
                        {
                            fadeOutPageAnswerTransition.Stop();
                            fadeOutPageAnswerTransition.Completed -= handler;
                            targetItem.Visibility = Visibility.Collapsed;
                            questionsListBox.UpdateLayout();
                        };
                        fadeOutPageAnswerTransition.Completed += handler;
                        fadeOutPageAnswerTransition.Begin();
                    }
                    else if (targetItem.Visibility == Visibility.Collapsed)
                    {
                        targetItem.Visibility = Visibility.Visible;
                        fadeInPageAnswerTransition.Stop();
                        Storyboard.SetTarget(fadeInTextAnimation, targetItem);
                        EventHandler eh = null;
                        eh = (s, args) =>
                        {
                            fadeInPageAnswerTransition.Stop();
                            fadeInPageAnswerTransition.Completed -= eh;
                            ScrollToQuestion();
                        };
                        fadeInPageAnswerTransition.Completed += eh;
                        fadeInPageAnswerTransition.Begin();
                    }
                    return;
                }
                else
                {
                    ToggleAnswerVisibility(child, controlName);
                }
            }

        }
        /// <summary>
        /// Hide trayProgress bar when questions have finished loading
        /// </summary>
        private void QuestionsNotLoading()
        {
            GlobalViewModel.HideProgressBar(trayProgressBar);
            _questionsScrambled = false;
        }

        /// <summary>
        /// Set trayProgress bar values and reset the questionsLoaded value.
        /// </summary>
        private void QuestionsLoading()
        {
            _questionsLoaded = 0;
            trayProgressBar.Text = AppResources.LoadingQAndA;
            trayProgressBar.IsVisible = true;
            trayProgressBar.Value = 0;
        }

        #region callback methods

        /// <summary>
        /// Callback method for sending question to author
        /// </summary>
        private void SendQuestionCallback(RestResponse restResponse, User user)
        {
            if (restResponse.ResponseStatus == ResponseStatus.Completed && restResponse.Content == "")
            {
                GlobalViewModel.ShowToast(AppResources.Success, AppResources.QuestionSent);
                studyPivot.SelectedItem = studyPivotItem;
                questionTextBox.Text = "";
                answerTextBox.Text = "";
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.QuestionNotSent);
            }
            GlobalViewModel.HideProgressBar(trayProgressBar);
        }

        #endregion

        #region App bar

        /// <summary>
        /// Creates new application bar with buttons and event handlers
        /// </summary>
        private void CreateAppBar()
        {
            ApplicationBar = new ApplicationBar { Opacity = 0, Mode = ApplicationBarMode.Minimized };
            _pageViewButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.page.rest.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.PageViewButton
            };

            _textSizeButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.text.rest.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.TextSizeButton
            };

            _switchButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.repeat.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.SwitchButtonText
            };
            _randomizeButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.shuffle.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.RandomizeButtonText
            };

            _proposeQuestionItem = new ApplicationBarMenuItem(AppResources.ProposeQuestion) { IsEnabled = App.CurrentUser.CurrentChapter.AllowProposals };

            ApplicationBar.StateChanged += AppBarStateChanged;

            _proposeQuestionItem.Click += ProposeQuestionItemClick;
            _pageViewButton.Click += PageViewButtonClick;
            _textSizeButton.Click += TextSizeButtonClick;
            _switchButton.Click += SwitchButtonClick;
            _randomizeButton.Click += RandomizeButtonClick;

            ApplicationBar.Buttons.Add(_pageViewButton);
            ApplicationBar.Buttons.Add(_switchButton);
            ApplicationBar.Buttons.Add(_textSizeButton);
            ApplicationBar.Buttons.Add(_randomizeButton);

            ApplicationBar.MenuItems.Add(_proposeQuestionItem);

            if (studyPivot.SelectedItem == pageViewPivotItem)
            {
                _pageViewButton.IsEnabled = false;
            }
        }
        private void CreateFontChangeAppBar()
        {
            ApplicationBar = new ApplicationBar { Opacity = 0.9 };
            var smallerFontButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.arrow.down.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.DecreaseFont
            };

            var acceptFontButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.check.rest.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.Save
            };

            var biggerFontButton = new ApplicationBarIconButton
            {
                IconUri = new Uri("/Images/appbar.arrow.up.png", UriKind.Relative),
                IsEnabled = true,
                Text = AppResources.IncreaseFont
            };
            smallerFontButton.Click += SmallerFontClicked;
            acceptFontButton.Click += AcceptFontClicked;
            biggerFontButton.Click += BiggerFontClicked;

            ApplicationBar.Buttons.Add(smallerFontButton);
            ApplicationBar.Buttons.Add(acceptFontButton);
            ApplicationBar.Buttons.Add(biggerFontButton);
        }
        #endregion

        #region eventHandlers
        /// <summary>
        /// When the font increase button is clicked.
        /// </summary>
        private void BiggerFontClicked(object sender, EventArgs e)
        {
            if (answerText.FontSize > 30)
            {
                GlobalViewModel.ShowToast(AppResources.Notification, AppResources.FontLargest);
                return;
            }
            ChangeFontSize(2);
        }

        /// <summary>
        /// When the accept font size button is clicked.
        /// </summary>
        private void AcceptFontClicked(object sender, EventArgs e)
        {
            App.CurrentUser.CurrentFontSize = answerText.FontSize;
            _changingFont = false;
            CreateAppBar();
        }

        /// <summary>
        /// When the decrease font size button is clicked.
        /// </summary>
        private void SmallerFontClicked(object sender, EventArgs e)
        {
            if (answerText.FontSize < 12)
            {
                GlobalViewModel.ShowToast(AppResources.Notification, AppResources.FontSmallest);
                return;
            }
            ChangeFontSize(-2);
        }

        /// <summary>
        /// Apply the supplied font size to the question and answer
        /// </summary>
        private void ApplyFontSize(double size)
        {
            answerText.FontSize = size;
            questionText.FontSize = size;

            if (studyPivot.SelectedItem == pageViewPivotItem)
            {
                UpdatePageViewFontSize(size);
                questionsListBox.UpdateLayout();
            }
        }

        /// <summary>
        /// Increase or decrease the font by the increment supplied
        /// </summary>
        private void ChangeFontSize(int increment)
        {
            answerText.FontSize += increment;
            questionText.FontSize += increment;

            if (studyPivot.SelectedItem == pageViewPivotItem)
            {
                UpdatePageViewFontSize(answerText.FontSize);
            }
        }

        /// <summary>
        /// When the I know the answer button is pressed.
        /// </summary>
        private void AnswerButtonOnTap(object sender, GestureEventArgs e)
        {
            e.Handled = true;
            KnowAnswerPressed(true);
            QuestionAnswered();
        }

        /// <summary>
        /// Gets next available question or returns null if no more questions are available.
        /// </summary>
        private Question GetNextQuestion(Question currentQuestion)
        {
            Question nextQuestion = null;
            var questions = App.CurrentUser.CurrentChapter.Questions.ToList();
            var element = questions.IndexOf(currentQuestion);
            for (var i = element + 1; i < questions.Count(); i++)
            {
                if (questions[i].AnsweredDate < DateTime.Now)
                {
                    nextQuestion = questions[i];
                    break;
                }
            }
            if (nextQuestion == null)
            {
                for (var j = 0; j < element; j++)
                {
                    if (questions[j].AnsweredDate < DateTime.Now)
                    {
                        nextQuestion = questions[j];
                        break;
                    }
                }
            }
            return nextQuestion;
        }

        /// <summary>
        /// Gets next available previous question or returns null if no more questions are available.
        /// </summary>
        private Question GetPreviousQuestion(Question currentQuestion)
        {
            Question previousQuestion = null;
            var questions = App.CurrentUser.CurrentChapter.Questions.ToList();
            var element = questions.IndexOf(currentQuestion);
            for (var i = element - 1; i >= 0; i--)
            {
                if (questions[i].AnsweredDate < DateTime.Now)
                {
                    previousQuestion = questions[i];
                    break;
                }
            }
            if (previousQuestion == null)
            {
                for (var j = questions.Count() - 1; j > element; j--)
                {
                    if (questions[j].AnsweredDate < DateTime.Now)
                    {
                        previousQuestion = questions[j];
                        break;
                    }
                }
            }
            return previousQuestion;
        }

        /// <summary>
        /// Set question as answered and update chapter progress
        /// </summary>
        private void QuestionAnswered()
        {
            App.CurrentUser.CurrentChapter.CurrentQuestion.AnswerCount += 1;
            App.CurrentUser.CurrentChapter.CurrentQuestion.AnsweredDate =
               DateTime.Now.AddDays(Math.Pow(3, App.CurrentUser.CurrentChapter.CurrentQuestion.AnswerCount));

            App.CurrentUser.CurrentChapter.UpdateQuestionWithCurrentQuestion(App.CurrentUser.CurrentChapter.CurrentQuestion);
            if (Chapter.AreAllQuestionsAnswered(App.CurrentUser.CurrentChapter))
            {
                knowAnswerButton.Visibility = Visibility.Collapsed;
                KnowAnswerPressed(false);
                NotificationTool.Show(AppResources.Congratulation, AppResources.NoMoreQuestions,
                    new NotificationAction(AppResources.Reset, () =>
                    {
                        StudyViewModel.ResetProgress(App.CurrentUser);
                        UpdateChapterProgress();
                        DisplayFirstQuestion();
                    }),
                    new NotificationAction(AppResources.Exit, () =>
                    {
                        NavigationService.Navigate(new Uri("/View/Books.xaml?fromStudyView", UriKind.Relative));
                        App.CurrentUser.CurrentChapter.CurrentQuestion = null;
                    }));
            } else
            {
                MoveToNext();
            }
            UpdateChapterProgress();
        }

        /// <summary>
        /// Event handler when propose question in application bar menu is clicked.
        /// </summary>
        private void ProposeQuestionItemClick(object sender, EventArgs eventArgs)
        {
            if (!App.CurrentUser.CurrentChapter.AllowProposals) return;
            studyPivot.Items.Add(sendQuestionPivotItem);
            studyPivot.SelectedItem = sendQuestionPivotItem;
        }

        /// <summary>
        /// Event handler when page view button on application is clicked.
        /// </summary>
        private void PageViewButtonClick(object sender, EventArgs eventArgs)
        {
            studyPivot.Items.Add(pageViewPivotItem);
            studyPivot.SelectedItem = pageViewPivotItem;
            UpdatePageViewList();
        }

        /// <summary>
        /// Event handler when text size button on application is clicked.
        /// </summary>
        private void TextSizeButtonClick(object sender, EventArgs eventArgs)
        {
            _changingFont = true;
            CreateFontChangeAppBar();
        }

        /// <summary>
        /// Event handler when switch Q/A button on application is clicked.
        /// </summary>
        private void SwitchButtonClick(object sender, EventArgs eventArgs)
        {
            foreach (var question in App.CurrentUser.CurrentChapter.Questions)
            {
                var answ = question.AnswerText;
                var qst = question.QuestionText;
                question.AnswerText = qst;
                question.QuestionText = answ;
            }
            var visibleQst = questionText.Text;
            questionText.Text = answerText.Text;
            answerText.Text = visibleQst;
            GlobalViewModel.ShowToast(AppResources.Notification, AppResources.QuestionAnswerSwapped);
        }

        /// <summary>
        /// Event handler when randomize button in appbar is clickeed
        /// </summary>
        private void RandomizeButtonClick(object sender, EventArgs e)
        {
            App.CurrentUser.CurrentChapter.Questions = GlobalViewModel.Randomize(App.CurrentUser.CurrentChapter.Questions);
            if (studyPivot.SelectedItem == pageViewPivotItem)
            {
                UpdatePageViewList();
                _questionsScrambled = true;
            }
            GlobalViewModel.ShowToast(AppResources.Success, AppResources.QuestionsScrambled);
        }

        /// <summary>
        /// Makes the application bar transparent if the menu is not opened
        /// </summary>
        private void AppBarStateChanged(object sender, ApplicationBarStateChangedEventArgs e)
        {
            ApplicationBar.Opacity = e.IsMenuVisible == false ? 0 : 0.9;
        }
        
        /// <summary>
        /// Back button event handler, with animation out.
        /// </summary>
        protected override void OnBackKeyPress(CancelEventArgs e)
        {
            e.Cancel = true;
            // Disable font increase mode when back key is pressed while it is activated, and reset font size to previous choice.
            if (_changingFont)
            {
                ApplyFontSize(App.CurrentUser.CurrentFontSize > 0 ? App.CurrentUser.CurrentFontSize : 20);
                _changingFont = false;
                CreateAppBar();
                return;
            }
            if (studyPivot.SelectedItem == studyPivotItem)
            {
                base.OnBackKeyPress(e);
                GlobalViewModel.ShowProgressBar(trayProgressBar, AppResources.SavingProgress);
                NavigationService.Navigate(new Uri("/View/Books.xaml?fromStudyView", UriKind.Relative));
                ShowHide(LayoutRoot, null, 0, -RenderSize.Width, 1, 0);
                
            }
            else
            {
                studyPivot.SelectedItem = studyPivotItem;
            }
        }

        /// <summary>
        /// Study view is switching to another page
        /// </summary>
        private void StudyPivotSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var currentItem = e.AddedItems[0] as PivotItem;
            var previousItem = e.RemovedItems[0] as PivotItem;
            if (previousItem == null || !studyPivot.Items.Contains(previousItem)) return;
            if (currentItem == sendQuestionPivotItem)
            {
                ShowAppBar(false);
                _proposeQuestionItem.IsEnabled = false;
            }
            else if (currentItem == pageViewPivotItem)
            {
                _pageViewButton.IsEnabled = false;
                _questionsScrambled = false;
            }
            // If "propose question" page is visible remove it when navigating away from it and re-enable the propose menu item if neccessary.
            if (previousItem == sendQuestionPivotItem)
            {
                ShowAppBar(true);
                studyPivot.Items.Remove(sendQuestionPivotItem);
                _proposeQuestionItem.IsEnabled = App.CurrentUser.CurrentChapter.AllowProposals;
            }
            else if (previousItem == pageViewPivotItem)
            {
                studyPivot.Items.Remove(pageViewPivotItem);
                _pageViewButton.IsEnabled = true;
            }
        }

        /// <summary>
        /// Send question button click event handler. Validates question and answer fields and initiates password change.
        /// </summary>h
        private void SendQuestionButtonClick(object sender, RoutedEventArgs e)
        {
            var question = questionTextBox.Text;
            var answer = answerTextBox.Text;
            if (StudyViewModel.ValidateQuestionProposal(question))
            {
                GlobalViewModel.ShowProgressBar(trayProgressBar, AppResources.SendingInProgress);
                _studyViewModel.SendQuestionWebRequest(App.CurrentUser, question, answer, SendQuestionCallback);
            }
        }

        /// <summary>
        /// Display the previous possible question
        /// </summary>
        private void MoveToPrevious()
        {
            _tapCount = 0;
            var newPreviousQuestion = GetPreviousQuestion(App.CurrentUser.CurrentChapter.CurrentQuestion);
            if (newPreviousQuestion != null)
            {
                slideOutToRightTransition.Completed += delegate
                                                           {
                                                               // Give textblocks new values
                                                               questionText.Text = newPreviousQuestion.QuestionText;
                                                               answerText.Text = newPreviousQuestion.AnswerText;
                                                               answerText.Visibility = Visibility.Visible;
                                                               answerBorder.Visibility = Visibility.Visible;
                                                               knowAnswerButton.Visibility = Visibility.Visible;
                                                               KnowAnswerPressed(false);

                                                               slideInFromLeftTransition.Begin();

                                                               App.CurrentUser.CurrentChapter.CurrentQuestion =
                                                                   newPreviousQuestion;
                                                           };
                slideOutToRightTransition.Begin();
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Notification, AppResources.LastQuestion);
            }

        }

        /// <summary>
        /// Display the next possible question
        /// </summary>
        private void MoveToNext()
        {
            _tapCount = 0;
            var newCurrentQuestion = GetNextQuestion(App.CurrentUser.CurrentChapter.CurrentQuestion);
            if (newCurrentQuestion != null)
            {
                slideOutToLeftTransition.Completed += delegate
                                                          {
                                                              // Give textblocks new values
                                                              questionText.Text = newCurrentQuestion.QuestionText;
                                                              answerText.Text = newCurrentQuestion.AnswerText;

                                                              answerText.Visibility = Visibility.Collapsed;
                                                              answerBorder.Visibility = Visibility.Collapsed;

                                                              knowAnswerButton.Visibility = Visibility.Collapsed;
                                                              KnowAnswerPressed(false);

                                                              slideInFromRightTransition.Begin();

                                                              App.CurrentUser.CurrentChapter.CurrentQuestion =
                                                                  newCurrentQuestion;

                                                          };
                slideOutToLeftTransition.Begin();
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Notification, AppResources.LastQuestion);
            }
            
        }

        /// <summary>
        /// Swipe event 
        /// </summary>
        private void OnFlick(object sender, FlickGestureEventArgs e)
        {
            // User flicked towards left
            if (e.HorizontalVelocity < 0 && (e.Direction == System.Windows.Controls.Orientation.Horizontal))
            {
                MoveToNext();
            }

            // User flicked towards right
            if (e.HorizontalVelocity > 0 && (e.Direction == System.Windows.Controls.Orientation.Horizontal))
            {
                MoveToPrevious();
            }
        }

        /// <summary>
        /// Tap on the study pivot. 1 tap = show answer, second tap = go to next question
        /// </summary>
        private void StudyPivotTap(object sender, GestureEventArgs e)
        {
            _tapCount++;
            if (_tapCount == 1 && answerText.Visibility != Visibility.Visible)
            {
                fadeInAnswerTransition.Begin();
                answerBorder.Visibility = Visibility.Visible;
                answerText.Visibility = Visibility.Visible;
                KnowAnswerPressed(false);
                knowAnswerButton.Visibility = Visibility.Visible;
            }
            else
            {
                MoveToNext();
            }
        }

        /// <summary>
        /// Tap on the sponsor logo event
        /// </summary>
        private void SponsorItemTap(object sender, GestureEventArgs e)
        {
            var stackpanel = sender as StackPanel;
            if (stackpanel == null) return;
            var grid = stackpanel.Parent as Grid;
            if (grid == null) return;
            var pivot = grid.Parent as PivotItem;
            if (pivot == null) return;
            // Check internet connection BEFORE redirecting to sponsor.xaml
            if (DeviceNetworkInformation.IsNetworkAvailable)
            {
                NavigationService.Navigate(new Uri(String.Format("/View/Sponsor.xaml?{0}", pivot.Name), UriKind.Relative));
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.InternetProblem);
            }
        }

        /// <summary>
        /// Hold gesture on a listbox item handler in page view
        /// </summary>
        private void QuestionsListBoxHold(object sender, GestureEventArgs e)
        {
            Question question = (sender as Grid).DataContext as Question;
            if (question != null)
            {
                if (question.AnsweredDate < DateTime.Now)
                {
                    App.CurrentUser.CurrentChapter.CurrentQuestion = question;
                    studyPivot.SelectedItem = studyPivotItem;
                    questionText.Text = App.CurrentUser.CurrentChapter.CurrentQuestion.QuestionText;
                    answerText.Text = App.CurrentUser.CurrentChapter.CurrentQuestion.AnswerText;
                }
                else
                {
                    GlobalViewModel.ShowToast(AppResources.Notification, AppResources.QuestionAnswered);
                }
            }
        }

        /// <summary>
        /// When a question is clicked in the questions list box in page view
        /// </summary>
        private void QuestionsListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //questionsListBox.UpdateLayout();
            var item = questionsListBox.ItemContainerGenerator.ContainerFromIndex(questionsListBox.SelectedIndex) as ListBoxItem;
            if (item != null)
            {
                ToggleAnswerVisibility(item, "answerPageViewBorder");
                ToggleAnswerVisibility(item, "answerPageViewText");
                
                
                //if opened question is tapped
                if (_selectedQuestion == item)
                {
                    _selectedQuestion = null;
                    questionsListBox.SelectedIndex = -1;
                }
                //another question is tapped
                else
                {
                    if (_selectedQuestion != null)
                    {
                        ToggleAnswerVisibility(_selectedQuestion, "answerPageViewBorder");                      
                        ToggleAnswerVisibility(_selectedQuestion, "answerPageViewText");
                    }
                    else
                        ScrollToQuestion();

                    _selectedQuestion = item;
                } 
            }
        }

        #endregion

        #region pageLoad Animation
        private static void ShowHide(UIElement item, Action callback, double leftFrom, double leftTo, double opacityFrom, double opacityTo)
        {
            // setup
            var translate = new TranslateTransform
            {
                X = leftFrom,
                Y = 0
            };
            item.RenderTransform = translate;
            item.Visibility = Visibility.Visible;
            item.Opacity = opacityFrom;

            // animate
            var storyboard = new Storyboard();
            var duration = TimeSpan.FromSeconds(.3);

            // opacity
            var opacityAnimate = new DoubleAnimation
            {
                To = opacityTo,
                Duration = duration,
            };
            storyboard.Children.Add(opacityAnimate);
            Storyboard.SetTarget(opacityAnimate, item);
            Storyboard.SetTargetProperty(opacityAnimate,
                new PropertyPath(UIElement.OpacityProperty));

            // translate (location)
            var translateAnimate = new DoubleAnimation
            {
                To = leftTo,
                Duration = duration,
                EasingFunction = new SineEase
                {
                    EasingMode = EasingMode.EaseOut
                }
            };
            storyboard.Children.Add(translateAnimate);
            Storyboard.SetTarget(translateAnimate, translate);
            Storyboard.SetTargetProperty(translateAnimate,
                new PropertyPath(TranslateTransform.XProperty));

            // finalize
            translateAnimate.Completed += (s, arg) =>
            {
                if (callback != null)
                    callback();
            };
            storyboard.Begin();
        }
        #endregion
    }
}